// 定义扇形接口
export interface Sector {
  radius1: number;
  radius2: number;
  angleStart: number;
  angleEnd: number;
}

// 根据方向和距离偏移坐标，距离以米为单位
export function metersToCoordinate(lon: number, lat: number, distanceInMeters: number, angle: number): [number, number] {
  const adjustedAngle = (450 - angle) % 360;
  const earthRadius = 6371000;
  const deltaLat = (distanceInMeters * Math.sin((adjustedAngle * Math.PI) / 180)) / earthRadius;
  const deltaLon =
    (distanceInMeters * Math.cos((adjustedAngle * Math.PI) / 180)) / (earthRadius * Math.cos((lat * Math.PI) / 180));
  const newLat = lat + (deltaLat * 180) / Math.PI;
  const newLon = lon + (deltaLon * 180) / Math.PI;
  return [newLon, newLat];
}

// 将经纬度数组转为 GeoJSON 格式的点
export function convertToPoint(lonLat: [number, number]): GeoJSON.Feature<GeoJSON.Point> {
  return {
    type: "Feature",
    geometry: {
      type: "Point",
      coordinates: lonLat
    },
    properties: {}
  };
}

// 将经纬度数组转为 GeoJSON 格式的线
export function convertToLine(lonLatArray: [number, number][]): GeoJSON.Feature<GeoJSON.LineString> {
  return {
    type: "Feature",
    geometry: {
      type: "LineString",
      coordinates: lonLatArray
    },
    properties: {}
  };
}

// 生成仰角文本
export function generateElevation(
  data: { distance: number; angle: number }[],
  center: [number, number]
): GeoJSON.Feature<GeoJSON.Point>[] {
  let elevationFeature: { data: [number, number]; label: string }[] = [];
  data.forEach(item => {
    const lonLat = metersToCoordinate(center[0], center[1], item.distance, 0);
    elevationFeature.push({ data: lonLat, label: item.angle + "°" });
  });
  return drawPoint(elevationFeature);
}

// 生成扇形
export function generateSectorShape(
  center: [number, number],
  radius1: number,
  radius2: number,
  angleStart: number,
  angleEnd: number
): GeoJSON.Feature<GeoJSON.Polygon> {
  const lon = center[0];
  const lat = center[1];
  let circleOuter: [number, number][] = [];
  for (let i = angleStart; i < angleEnd; i++) {
    circleOuter.push(metersToCoordinate(lon, lat, radius1, i));
  }
  let circleInner: [number, number][] = [];
  for (let i = angleStart; i < angleEnd; i++) {
    circleInner.push(metersToCoordinate(lon, lat, radius2, i));
  }
  circleInner.unshift(circleOuter[0]);
  circleInner.push(circleOuter[circleOuter.length - 1]);
  const coordinates = [circleInner.concat(circleOuter.reverse())];
  return {
    type: "Feature",
    geometry: {
      type: "Polygon",
      coordinates: coordinates
    },
    properties: {}
  };
}

// 绘制圆
export function drawACircle(
  data: { distance: number }[],
  center: [number, number],
  isDashed = true
): GeoJSON.Feature<GeoJSON.LineString>[] {
  let circleData: GeoJSON.Feature<GeoJSON.LineString>[] = [];
  for (let j = 0; j < data.length; j++) {
    const element = data[j];
    let circleItem: [number, number][] = [];
    for (let i = 0; i < 361; i++) {
      circleItem.push(metersToCoordinate(center[0], center[1], element.distance, i));
    }
    const geoJson = convertToLine(circleItem);
    geoJson.properties = {
      ...geoJson.properties,
      style: {
        isDashed: isDashed,
        strokeWidth: 1
      }
    };
    circleData.push(geoJson);
  }
  return circleData;
}

// 绘制线
export function drawLine(
  distance: number,
  center: [number, number]
): (GeoJSON.Feature<GeoJSON.LineString> | GeoJSON.Feature<GeoJSON.Point>)[] {
  let lineData: GeoJSON.Feature<GeoJSON.LineString>[] = [];
  let pointData: { data: [number, number]; label: string }[] = [];
  for (let i = 0; i < 360; i += 15) {
    const lineItem = [center, metersToCoordinate(center[0], center[1], distance, i)];
    const geoJson = convertToLine(lineItem);
    if (![0, 45, 90, 135, 180, 225, 270, 315].includes(i)) {
      geoJson.properties = {
        ...geoJson.properties,
        style: {
          isDashed: true,
          strokeWidth: 1
        }
      };
    } else {
      pointData.push({ data: metersToCoordinate(center[0], center[1], distance, i), label: i + "°" });
    }
    lineData.push(geoJson);
  }
  const pointDatas = drawPoint(pointData);
  return lineData.concat(pointDatas);
}

// 创建标签 原理加载点，其实只显示 text
export function drawPoint(coord: { data: [number, number]; label: string }[], radius = 5): GeoJSON.Feature<GeoJSON.Point>[] {
  let pointFeature: GeoJSON.Feature<GeoJSON.Point>[] = [];
  coord.forEach(item => {
    let geoJson = convertToPoint(item.data);
    geoJson.properties = {
      ...geoJson.properties,
      color: "blue",
      text: item.label,
      radius
    };
    pointFeature.push(geoJson);
  });
  return pointFeature;
}

// 生成距离标识，默认向东 90 度计算
export function generateDistanceIdentification(
  center: [number, number]
): (GeoJSON.Feature<GeoJSON.Point> | GeoJSON.Feature<GeoJSON.LineString>)[] {
  let kilometreFeature: { data: [number, number]; label: string }[] = [];
  let kilometreCircleFeature: { distance: number }[] = [];
  for (let i = 1; i <= 10; i++) {
    const coordinate = metersToCoordinate(center[0], center[1], i * 1000, 90);
    if (i === 1 || i === 10) {
      kilometreFeature.push({ data: coordinate, label: i + "km" });
    } else {
      kilometreFeature.push({ data: coordinate, label: "" });
    }
  }
  const feature = drawPoint(kilometreFeature, 4);
  kilometreCircleFeature.push({ distance: 1000 }, { distance: 10000 });
  const circleFeature = drawACircle(kilometreCircleFeature, center, false);
  return feature.concat(circleFeature);
}
